package utils

import cats.implicits._

import java.io.IOException
import java.net.{ MalformedURLException, URI }
import java.util.Base64
import javax.imageio.{ ImageIO, ImageReader }
import javax.imageio.stream.ImageInputStream

import org.apache.commons.io.IOUtils

import scala.concurrent.{ ExecutionContext, Future }
import scala.util.Try

object ImageUtils extends ArcherHelper {

  def imageCatch(implicit ec: ExecutionContext) = commonCatch.withErrorHandler {
    msg =>
      {
        case e1: MalformedURLException =>
          val newMsg = msg.copy(log = Option("找不到图片文件"), user = "找不到图片文件")
          commonCatch.loggerOperation(newMsg, e1)
          ErrorResult(newMsg.user)
        case e2: IOException =>
          val newMsg = msg.copy(log = Option("找不到图片文件"), user = "找不到图片文件")
          commonCatch.loggerOperation(newMsg, e2)
          ErrorResult(newMsg.user)
        case e: Exception =>
          val newMsg = msg.copy(log = Option("解释图片格式出错"), user = "解释图片格式出错")
          commonCatch.loggerOperation(newMsg, e)
          ErrorResult(newMsg.user)
      }
  }

  def toBase64(uri: URI)(implicit ec: ExecutionContext): V.ResultT[String] = { // 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
    etLess.lift {
      val formatName = etLess.unlift(getFormatNameF(uri))
      val resultF = Future {
        val bytes = IOUtils.toByteArray(uri)
        // 对字节数组Base64编码
        s"""data:image/${formatName};base64,${
          new String(
            Base64.getEncoder.encode(bytes),
            "utf-8")
        }"""
      } /*.attemptT.leftMap {
        case e: IOException =>
          ErrorResult("找不到图片文件")
        case _ =>
          ErrorResult("为之错误")
      }*/
      etLess.unlift(imageCatch.apply(resultF))
    }
  }

  def getFormatNameF(uri: URI)(implicit ec: ExecutionContext): V.ResultT[String] = { // 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
    var bufferedImage: ImageInputStream = null
    var imageReader: java.util.Iterator[ImageReader] = null
    val resultF = Future {
      val formatEither = {
        bufferedImage = ImageIO.createImageInputStream(uri.toURL.openStream)
        imageReader = ImageIO.getImageReaders(bufferedImage)
        if (imageReader.hasNext) {
          Right(imageReader.next.getFormatName)
        } else {
          Left(ErrorResult("不能识别的图片格式"))
        }
      }
      V.fromEither(formatEither)
    }.andThen {
      case _ =>
        Try(if (bufferedImage != null) bufferedImage.close())
          .fold(e => e.printStackTrace, (_: Unit) => ())
    }
    imageCatch.apply(resultF).flatMap(identity)
    /*var bufferedImage: ImageInputStream = null
    var imageReader: java.util.Iterator[ImageReader] = null
    val resultF = Future {
      val formatEither = try {
        bufferedImage = ImageIO.createImageInputStream(uri.toURL.openStream())
        imageReader = ImageIO.getImageReaders(bufferedImage)
        if (imageReader.hasNext) {
          Right(imageReader.next.getFormatName)
        } else {
          Left(ErrorResult("不能识别的图片格式"))
        }
      } catch {
        case e1: MalformedURLException =>
          e1.printStackTrace
          Left(ErrorResult("找不到图片文件"))
        case e2: IOException =>
          e2.printStackTrace
          Left(ErrorResult("找不到图片文件"))
      }
      V.fromEither(formatEither)
    }.andThen {
      case _ =>
        Try(if (bufferedImage != null) bufferedImage.close())
          .fold(e => e.printStackTrace, (_: Unit) => ())
    }.attemptT.leftMap { e =>
      logger.error("解释图片格式出错", e)
      ErrorResult("不可识别的错误")
    }
    resultF.flatMap(identity)*/
  }

}
